package com.android.wlw_local;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.android.commonlib.loop.HandlerLooper;
import com.android.commonlib.netlib.RemoteService;
import com.android.commonlib.netlib.RequestCallback;
import com.android.wlw_local.camera.CameraActivity;
import com.android.wlw_local.login.UserStore;
import com.android.wlw_local.otg.OTGConfigStore;
import com.android.wlw_local.protocol.ProtocaolTypes;
import com.android.wlw_local.protocol.ProtocolEntity;
import com.android.wlw_local.service.SendUtils;
import com.farsunset.cim.sdk.android.CIMEventListener;
import com.farsunset.cim.sdk.android.CIMListenerManager;
import com.farsunset.cim.sdk.android.model.ReplyBody;
import com.farsunset.cim.sdk.android.model.SentBody;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.w3c.dom.Text;

import java.io.IOException;
import java.util.Random;


import tw.com.prolific.driver.pl2303.PL2303Driver;

public class MainActivity extends FragmentActivity {
    public static final String TAG = MainActivity.class.getSimpleName();

    private WorkPlanFragment workPlanFragment ;

    private EditText inputEt ;
    private Button sendBtn ;

    private TextView onoffline ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addFragment();
        initView();
        initData();
        registerEventBus();
        initSerial();
        runLoop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
        if(!mSerial.isConnected()) {
            AppApplication.getAppApplication().isTerminalOnline = false ;
            if( !mSerial.enumerate() ) {
                Toast.makeText(this, "no more devices found", Toast.LENGTH_SHORT).show();
                return;
            } else {
                Log.d(TAG, "onResume:enumerate succeeded!");
            }
        }
        AppApplication.getAppApplication().isTerminalOnline = true ;
        onoffline.setText((AppApplication.getAppApplication().isOriginOnline ? "远端在线":"远端离线") + (AppApplication.getAppApplication().isTerminalOnline ? "OTG在线":"OTG离线") );
    }

    private void initView(){
        inputEt = (EditText) findViewById(R.id.input);
        sendBtn = (Button) findViewById(R.id.send);
        onoffline = (TextView) findViewById(R.id.onoffline);
        onoffline.setText((AppApplication.getAppApplication().isOriginOnline ? "远端在线":"远端离线") + (AppApplication.getAppApplication().isTerminalOnline ? "OTG在线":"OTG离线") );
        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!TextUtils.isEmpty(inputEt.getText().toString())){
                    writeDataToSerial(inputEt.getText().toString());
                }
            }
        });

        registerMegListener();
    }

    private void addFragment(){
        /**
         * 工作计划
         */
        if(workPlanFragment == null){
            workPlanFragment = WorkPlanFragment.newInstance();
        }
        getSupportFragmentManager().beginTransaction().add(R.id.contentFrameLayout,workPlanFragment,"workplan").commit();
    }

    private void initData(){


    }



    private void registerMegListener(){
        if(cimEventListener != null) {
            CIMListenerManager.registerMessageListener(cimEventListener);
        }
    }

    private void removeMsgListener(){
        if(cimEventListener != null) {
            CIMListenerManager.removeMessageListener(cimEventListener);
        }
    }

    CIMEventListener cimEventListener = new CIMEventListener() {
        @Override
        public void onMessageReceived(com.farsunset.cim.sdk.android.model.Message message) {

        }

        @Override
        public void onReplyReceived(ReplyBody replyBody) {
            if(replyBody != null&& replyBody.get("isOnline")!= null  && replyBody.get("isOnline").equals("true")){
                //远端在线
                AppApplication.getAppApplication().isOriginOnline = true ;
                onoffline.setText((AppApplication.getAppApplication().isOriginOnline ? "远端在线":"远端离线") + (AppApplication.getAppApplication().isTerminalOnline ? "OTG在线":"OTG离线") );
            }
            if(replyBody!= null && !TextUtils.isEmpty(replyBody.get("message"))){
                String msg = replyBody.get("message");
                ProtocolEntity res = ProtocolEntity.praseEntity(msg);
                if(res != null ){
                    switch (res.getType()){
                        case ProtocaolTypes.PROTOCOL_TYPE_CAMERA://拍照
                            startActivityForResult(new Intent(MainActivity.this, CameraActivity.class) ,REQUEST_CAMERA_CODE);
                            break;
                        case ProtocaolTypes.PROTOCOL_TYPE_MSG:
                            String commond = res.getValue();
                            writeDataToSerial(commond);
                            Toast.makeText(MainActivity.this,"指令接受，已发送给OTG",Toast.LENGTH_SHORT).show();
                            break;
                    }
                }
            }
        }

        @Override
        public void onSentSuccessed(SentBody sentBody) {

        }

        @Override
        public void onNetworkChanged(NetworkInfo networkInfo) {

        }

        @Override
        public void onConnectionSuccessed(boolean b) {

        }

        @Override
        public void onConnectionClosed() {

        }

        @Override
        public void onConnectionFailed() {

        }

        @Override
        public int getEventDispatchOrder() {
            return 0;
        }
    };

    public static final int REQUEST_CAMERA_CODE = 0X101 ;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(data!= null && requestCode == REQUEST_CAMERA_CODE){
            String picFilePath = data.getStringExtra("camera_file_path");
            Toast.makeText(MainActivity.this,"拍照成功",Toast.LENGTH_SHORT).show();
            uploadimg(picFilePath);
        }

    }

    private void uploadimg(String path){
        RemoteService.getInstance().invokeFile("uploadImage", UserStore.getInstance().getUsername(),"jpg",path,new RequestCallback(){
            @Override
            public void onSuccess(String content) {
                //拍照成功
                SendUtils.sendMessage(MainActivity.this, ProtocolEntity.toJsonStr(new ProtocolEntity(ProtocaolTypes.PROTOCOL_TYPE_CAMERA_CALLBACK,content)));
            }
            @Override
            public void onFail(String errorMessage) {
                Toast.makeText(MainActivity.this,"上传失败",Toast.LENGTH_SHORT).show();
                //拍照失败
                SendUtils.sendMessage(MainActivity.this, ProtocolEntity.toJsonStr(new ProtocolEntity(ProtocaolTypes.PROTOCOL_TYPE_CAMERA_CALLBACK,"fail")));
            }
            @Override
            public void showDialog() {

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        isRun = false ;
        removeMsgListener();
        removeEventBus();
        loopHandler.removeMessages(0);
    }

    Handler delayHandler = new Handler();
    @Override
    protected void onStart() {
        super.onStart();
        if(!mSerial.isConnected()){
            openUsbSerial();
        }
        AppApplication.getAppApplication().isTerminalOnline = true ;
        onoffline.setText((AppApplication.getAppApplication().isOriginOnline ? "远端在线":"远端离线") + (AppApplication.getAppApplication().isTerminalOnline ? "OTG在线":"OTG离线") );
        sendBaseMsg();
    }
    private int i =0 ;
    private void sendBaseMsg(){
        delayHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if(i == 0) {
                    writeDataToSerial("M105\n");
                }else if(i == 1){
                    writeDataToSerial("M505\n");
                }else {
                    delayHandler.removeMessages(0);
                }
                i++ ;
            }
        },1000);
    }

    /**************************EventBus*********************************************/
    private void registerEventBus(){
        EventBus.getDefault().register(this);
    }

    private void removeEventBus(){
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onAcceptRes(String resOTG) {
        if(resOTG.equals("startLoopByTemp")){
            if(tempHandlerLooper!= null){
                tempHandlerLooper.onDestory();
                tempHandlerLooper = null;
            }
            tempHandlerLooper = HandlerLooper.getInstante();
            tempHandlerLooper.onStart(10 * 60 * 1000, new HandlerLooper.TaskContent() {
                @Override
                public void excuteTask() {
                    writeDataToSerial("M105\\n");
                }
            });
        }else if(resOTG.equals("startLoopByWaterLevel")){
            if(waterLevelHandlerLooper != null){
                waterLevelHandlerLooper.onDestory();
                waterLevelHandlerLooper = null ;
            }
            waterLevelHandlerLooper = HandlerLooper.getInstante();
            waterLevelHandlerLooper.onStart(10 * 60 * 1000, new HandlerLooper.TaskContent() {
                @Override
                public void excuteTask() {
                    writeDataToSerial("M505\\n");
                }
            });
        }else {
            writeDataToSerial(resOTG);
        }

    }

    /**************************EventBus*********************************************/



    /**************************OTG*********************************************/

    /**USB 权限**/
    private static final String ACTION_USB_PERMISSION = "com.prolific.pl2303hxdsimpletest.USB_PERMISSION";

    private PL2303Driver mSerial;

    private PL2303Driver.BaudRate mBaudrate = PL2303Driver.BaudRate.B9600;
    private PL2303Driver.DataBits mDataBits = PL2303Driver.DataBits.D8;
    private PL2303Driver.Parity mParity = PL2303Driver.Parity.NONE;
    private PL2303Driver.StopBits mStopBits = PL2303Driver.StopBits.S1;
    private PL2303Driver.FlowControl mFlowControl = PL2303Driver.FlowControl.OFF;

    private boolean isRun = true ;

    private Thread loopThread ;


    private HandlerLooper tempHandlerLooper ;

    private HandlerLooper waterLevelHandlerLooper ;

    @SuppressLint("HandlerLeak")
    private Handler loopHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle b = msg.getData();
            String backRes = b.getString("value");
            if(TextUtils.isEmpty(backRes)){
                Toast.makeText(MainActivity.this,"res:"+backRes,Toast.LENGTH_LONG).show();
                return;
            }
            Toast.makeText(MainActivity.this,"res:"+backRes,Toast.LENGTH_LONG).show();
            if(backRes.equals("ok\n")){//表示可以接受下一条命令
                AppApplication.getAppApplication().isOk = true ;
            }else if(backRes.equals("K")){//紧急命令

            }else if(backRes.startsWith("O:")){//水位
//                workPlanFragment.setTemperature_tv(backRes.replace("O:",""));
            }else if(backRes.equals("JOK")){//加水完毕

            }else if(backRes.startsWith("S1:")){//湿度

            }else if(backRes.startsWith("H:")){//水位
                workPlanFragment.setwater_tv(backRes.replace("H:",""));
            }else if(backRes.startsWith("C:")){//X Y Z E 移动

            }else if(backRes.startsWith("T:")){//T: B://温度1 温度2
                String[] str = backRes.split(":");
                if(str.length > 2) {
                    workPlanFragment.setTemperature_tv(str[1]);
                }else if(str.length >= 4){
                    workPlanFragment.setTemperature_tv(str[1] + "   " + str[3]);
                }
            }
            //转发给远程端
            SendUtils.sendMessage(MainActivity.this,ProtocolEntity.toJsonStr(new ProtocolEntity(ProtocaolTypes.PROTOCOL_TYPE_MSG,backRes)));
        }
    };


    private void initSerial(){
        mSerial = new PL2303Driver((UsbManager) getSystemService(Context.USB_SERVICE),this, ACTION_USB_PERMISSION);
        // check USB host function.
        if (!mSerial.PL2303USBFeatureSupported()) {
            Toast.makeText(this, "No Support USB host API", Toast.LENGTH_SHORT) .show();
            mSerial = null;
        }
        openUsbSerial();
    }



    public void openUsbSerial() {
        if(null==mSerial)
            return;

        if (mSerial.isConnected()) {
            int baudRate= OTGConfigStore.BPS115200;
            switch (baudRate) {
                case OTGConfigStore.BPS9600:
                    mBaudrate = PL2303Driver.BaudRate.B9600;
                    break;
                case OTGConfigStore.BPS19200:
                    mBaudrate =PL2303Driver.BaudRate.B19200;
                    break;
                case OTGConfigStore.BPS115200:
                    mBaudrate =PL2303Driver.BaudRate.B115200;
                    break;
                default:
                    mBaudrate =PL2303Driver.BaudRate.B115200;
                    break;
            }
            Toast.makeText(this, "start : " , Toast.LENGTH_SHORT).show();
            // if (!mSerial.InitByBaudRate(mBaudrate)) {
            if (!mSerial.InitByBaudRate(mBaudrate,700)) {
                if(!mSerial.PL2303Device_IsHasPermission()) {
                    Toast.makeText(this, "cannot open, maybe no permission", Toast.LENGTH_SHORT).show();
                }
                if(mSerial.PL2303Device_IsHasPermission() && (!mSerial.PL2303Device_IsSupportChip())) {
                    Toast.makeText(this, "cannot open, maybe this chip has no support, please use PL2303HXD / RA / EA chip.", Toast.LENGTH_SHORT).show();
                }
                Toast.makeText(this, "initByBaudRate", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "connected : " , Toast.LENGTH_SHORT).show();
            }
        }else {
            Toast.makeText(this, "unConnected : " , Toast.LENGTH_SHORT).show();
        }

    }//openUsbSerial

    public void runLoop() {
            loopThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (isRun) {

                        int len;
                        // byte[] rbuf = new byte[4096];
                        byte[] rbuf = new byte[20];
                        StringBuffer sbHex = new StringBuffer();

                        Log.d(TAG, "Enter readDataFromSerial");

                        if (null == mSerial) {
                        }
                        if (!mSerial.isConnected()) {
                        }

                        len = mSerial.read(rbuf);
                        if (len < 0) {
                            Log.d(TAG, "Fail to bulkTransfer(read data)");

                        }

                        if (len > 0) {
                            //rbuf[len] = 0;
                            for (int j = 0; j < len; j++) {
                                //String temp=Integer.toHexString(rbuf[j]&0x000000FF);
                                //Log.i(TAG, "str_rbuf["+j+"]="+temp);
                                //int decimal = Integer.parseInt(temp, 16);
                                //Log.i(TAG, "dec["+j+"]="+decimal);
                                //sbHex.append((char)decimal);
                                //sbHex.append(temp);
                                sbHex.append((char) (rbuf[j] & 0x000000FF));
                            }
                            Message msg = new Message();
                            msg.what = 555 ;
                            Bundle bundle = new Bundle();
                            bundle.putString("value", sbHex.toString());
                            msg.setData(bundle);
                            loopHandler.sendMessage(msg);
//                            return;
                        }else{
                            Message msg = new Message();
                            Bundle bundle = new Bundle();
                            bundle.putString("value", "");
                            msg.setData(bundle);
                            loopHandler.sendMessage(msg);
                        }
//                        msgHandler.sendEmptyMessage(666);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        loopThread.start();
    }



    public void writeDataToSerial(String text) {
        Log.d(TAG, "Enter writeDataToSerial");

        if(null==mSerial)
            return;

        if(!mSerial.isConnected())
            return;
        int res = mSerial.write(text.getBytes(), text.length());
        if( res<0 ) {
            Log.d(TAG, "setup2: fail to controlTransfer: "+ res);
            Toast.makeText(MainActivity.this,"fail",Toast.LENGTH_LONG).show();
            return;
        }
        Toast.makeText(MainActivity.this,"text"+res,Toast.LENGTH_LONG).show();
    }



    private void readDataFromSerial() {

        int len;
        // byte[] rbuf = new byte[4096];
        byte[] rbuf = new byte[20];
        StringBuffer sbHex=new StringBuffer();

        Log.d(TAG, "Enter readDataFromSerial");

        if(null==mSerial)
            return;

        if(!mSerial.isConnected())
            return;

        len = mSerial.read(rbuf);
        if(len<0) {
            Log.d(TAG, "Fail to bulkTransfer(read data)");
            return;
        }

        if (len > 0) {
            //rbuf[len] = 0;
            for (int j = 0; j < len; j++) {
                //String temp=Integer.toHexString(rbuf[j]&0x000000FF);
                //Log.i(TAG, "str_rbuf["+j+"]="+temp);
                //int decimal = Integer.parseInt(temp, 16);
                //Log.i(TAG, "dec["+j+"]="+decimal);
                //sbHex.append((char)decimal);
                //sbHex.append(temp);
                sbHex.append((char) (rbuf[j]&0x000000FF));
            }
            Toast.makeText(this, "res="+sbHex.toString(), Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(this, "res="+sbHex.toString(), Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "Leave readDataFromSerial");
    }//readDataFromSerial

}
